<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
	<title>jQuery拖拽插件Magnet.js</title>
	 <style>
      body {
        margin: 0;
      }
      * { font-size: 3vmin; }
      #lines, #paper {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
      }
      #paper {
        display: flex;
        flex-flow: column;
      }
      #tool {
        padding: 1vmin;
        background-color: #eee;
        font-family: monospace;
        line-height: 150%;
      }
      #container {
        flex: 2 2;
      }
      .item { white-space: nowrap; }
      input, button {
        outline: none;
        border: .1vmin solid #666;
        font-family: monospace;
        color: #333;
      }
      input[type=checkbox] {
        width: 3vmin;
        height: 3vmin;
      }
      button { background-color: #eee; }
      button:active { transform: translate(.1vmin, .1vmin); }
      #lines {
        z-index: 1;
        pointer-events: none;
      }
      #lines >* {
        position: absolute;
        width: 1px;
        height: 1px;
        background-color: #999;
        opacity: 0;
      }
      #lines >.show { opacity: .5; }
      #lines .vert {
        transform: translateX(-50%);
        height: 100%;
      }
      #lines .hori {
        transform: translateY(-50%);
        width: 100%;
      }
      .block {
        position: absolute;
        overflow: auto;
      }
      .block input {
        position: absolute;
        top: 0;
        right: 0;
      }
    </style>
</head>
<body>
	<div id="lines">
      <span class="vert"></span>
      <span class="hori"></span>
    </div>
    <div id="paper">
      <span id="tool">
        <span class="item">吸附距离: <input id="dist" type="number" min="0" max="20" /></span>
        <button id="add">新增盒子</button>
          <button onclick="addBox(4,4)">新增盒子</button>
        <span class="item"><input id="fix" type="checkbox" /><label for="fix">Fix edge（固定画布）</label></span>
        <span class="item"><input id="parentMiddle" type="checkbox" /><label for="parentMiddle">Align Parent Middle（盒子居中对齐）</label></span>
        <span class="item"><input id="outside" type="checkbox" /><label for="outside">Align Outside（外部对齐）</label></span>
        <span class="item"><input id="inside" type="checkbox" /><label for="inside">Align Inside（内部对齐）</label></span>
        <span class="item"><input id="middle" type="checkbox" /><label for="middle">Align Middle（父级居中对齐）</label></span>
      </span>
      <div id="container"></div>
    </div>

	<script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
	<script src="js/jquery-magnet.min.js"></script>
	<script>
      (($) => {
        const $window = $(window);
        const $magnet = $.magnet({
            distance: 10,//吸附距离初始值
            stayInParent: false,//固定画布初始值
            alignOuter:false,//外部对其初始值
            alignInner:false,//内部对齐初始值
            alignParentCenter:false,//盒子父级居中对齐
            alignCenter:false,//父级居中对齐
        });

        $window.on('load', () => {
          const $container = $('#container');
          const $mask = $('#lines');
          const $horiMagnet = $mask.find('.hori');
          const $vertMagnet = $mask.find('.vert');

          $magnet
            .on('start change end', ({ type }) => {
              console.log(`magnet${type}`);
            })
            .on('end', () => {
              $horiMagnet.removeClass('show');
              $vertMagnet.removeClass('show');
            })
            .on('change', (e) => {
              // show/hide horizon/vertical edge line
              let result = e.detail;
              let resultX = result.x;
              let resultY = result.y;
              if (resultX) {
                $vertMagnet.css('left', (resultX.position+'px'));
                $vertMagnet.addClass('show');
              } else {
                $vertMagnet.removeClass('show');
              }
              if (resultY) {
                $horiMagnet.css('top', (resultY.position+'px'));
                $horiMagnet.addClass('show');
              } else {
                $horiMagnet.removeClass('show');
              }
            });

          // generate block
          function genBlock() {
            const rootWidth = $window.width();
            const rootHeight = $window.height();
            const width = Math.max(30, parseInt(Math.random()*rootWidth/2)); //随机盒子宽
            const height = Math.max(30, parseInt(Math.random()*rootHeight/2)); //随机盒子高
            //创建 checkbox
            const $checkbox = $('<input>')
              .attr('type', 'checkbox')
              .prop('checked', true)
              .on('mousedown touchstart', (evt) => evt.stopPropagation())
              .on('change', function() {
                let block = this.parentNode;
                if (this.checked) {
                  block.style.resize = 'none';//设定不可调整 宽高
                  $magnet.add(block);
                } else {
                  block.style.resize = 'both';//设定用户可调整元素的高度和宽度。
                  $magnet.remove(block);
                }
              });
            const $block = $('<span>')
              .css({
                width: `${width}px`,
                height: `${height}px`,
                top: `${parseInt(Math.random()*(rootHeight-height))}px`,
                left: `${parseInt(Math.random()*(rootWidth-width))}px`,
                backgroundColor: `rgba(${[0, 0, 0].map(() => parseInt(100+Math.random()*155)).concat(.25+(.75*Math.random())).join(', ')})`,
              })
              .addClass('block')
              .on('mousedown', function(e) {
                this.style.zIndex = 10;
              })
              .on('click', function() {
                this.style.zIndex = 1;
                $(this).parent().append(this);
              })
              .on('dblclick', function() {
                const $checkbox = $(this).find('input[type=checkbox]');
                const checked = $checkbox.prop('checked');
                $checkbox.prop('checked', !checked);
                if (checked) {
                  $magnet.add(this);
                } else {
                  $magnet.remove(this);
                }
              })
              .on('attract unattract attracted unattracted', function(e) {
                console.log(e.type, e);
              })
              .append($checkbox)
              .appendTo($container);
            return $block;
          }

          //创建box
                addBox = function(row,column) {
                const rootWidth = $window.width();
                const rootHeight = $window.height();
                const item = {
                    width:150,
                    height:100
                }
                const width = item.width*row; //随机盒子宽
                const height = item.height*column; //随机盒子高
                //创建 checkbox
                const $checkbox = $('<input>')
                    .attr('type', 'checkbox')
                    .prop('checked', true)
                    .on('mousedown touchstart', (evt) => evt.stopPropagation())
                    .on('change', function() {
                        let block = this.parentNode;
                        if (this.checked) {
                            block.style.resize = 'none';//设定不可调整 宽高
                            $magnet.add(block);
                        } else {
                            block.style.resize = 'both';//设定用户可调整元素的高度和宽度。
                            $magnet.remove(block);
                        }
                    });
                const $block = $('<span>')
                    .css({
                        width: `${width}px`,
                        height: `${height}px`,
                        top: `${parseInt(Math.random()*(rootHeight-height))}px`,
                        left: `${parseInt(Math.random()*(rootWidth-width))}px`,
                        backgroundColor: `rgba(${[0, 0, 0].map(() => parseInt(100+Math.random()*155)).concat(.25+(.75*Math.random())).join(', ')})`,
                    })
                    .addClass('block')
                    .on('mousedown', function(e) {
                        this.style.zIndex = 10;
                    })
                    .on('click', function() {
                        this.style.zIndex = 1;
                        $(this).parent().append(this);
                    })
                    .on('dblclick', function() {
                        const $checkbox = $(this).find('input[type=checkbox]');
                        const checked = $checkbox.prop('checked');
                        $checkbox.prop('checked', !checked);
                        if (checked) {
                            $magnet.add(this);
                        } else {
                            $magnet.remove(this);
                        }
                    })
                    .on('attract unattract attracted unattracted', function(e) {
                        console.log(e.type, e);
                    })
                    .append($checkbox)
                    .appendTo($container);
                return $block;
            }

            // distance
          $('#dist')
            .on('change', function() {
              $magnet.distance(this.value);
            })
            .val($magnet.distance());

          // add one block
          $('#add').on('click', () => {
              console.log('添加一个 盒子')
            $magnet.add(genBlock());
          });
            $('#addBox').on('click', () => {
                console.log('添加一个 盒子')
                $magnet.add(genBlock2());
            });


          // enable/disable fix edge
          $('#fix')
            .on('change', function() {
              $magnet.stayInParent(this.checked);
            })
            .prop('checked', $magnet.stayInParent());

          // enable/disable align parent middle
          $('#parentMiddle')
            .on('change', function() {
              $magnet.alignParentCenter(this.checked);
            })
            .prop('checked', $magnet.alignParentCenter());

          // enable/disable align outside
          $('#outside')
            .on('change', function() {
              $magnet.alignOuter(this.checked);
            })
            .prop('checked', $magnet.alignOuter());

          // enable/disable align inside
          $('#inside')
            .on('change', function() {
              $magnet.alignInner(this.checked);
            })
            .prop('checked', $magnet.alignInner());

          // enable/disable align middle
          $('#middle')
            .on('change', function() {
              $magnet.alignCenter(this.checked);
            })
            .prop('checked', $magnet.alignCenter());

          // init blocks 初始化 加载 box
              // for (let bInx=(2+parseInt(Math.random()*3)); 0<bInx; bInx--) {
              //   $magnet.add(genBlock());
              // }
          // for (let bInx=0; bInx<(2+parseInt(Math.random()*3)); bInx++) {
          //   $magnet.add(genBlock());
          // }
        });
      })(jQuery);
    </script>
</body>
</html>